//Erstellt von Moritz Liepe
package main.editor;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import main.Activator;
import main.Module;
import main.ModuleEditor;
import main.Selector;
import main.XMLParser;
import main.XMLWriter;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.FigureCanvas;
import org.eclipse.draw2d.MouseEvent;
import org.eclipse.draw2d.MouseListener;
import org.eclipse.draw2d.MouseMotionListener;
import org.eclipse.draw2d.ScrollPane;
import org.eclipse.draw2d.XYLayout;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.EditorPart;



public class VOSEditor extends EditorPart implements ISelectionProvider,Listener
{
	
	public static final String ID = VOSEditor.class.getCanonicalName();
	
	private boolean dirty = false;
	
    private int xAdjust = 0, yAdjust = 0;
	
    private String filename = null;

	private final Figure appContents = new Figure();
	private final XYLayout appContentsLayout = new XYLayout();
	private final Selector selector = new Selector();
	private final ScrollPane selectorPane = new ScrollPane();
	private final ScrollPane editorPane = new ScrollPane();
	private final ModuleEditor editor = new ModuleEditor();
	private XMLParser parser;
	
	private FigureCanvas canvas;
	
	private StructuredSelection structuredSelection = StructuredSelection.EMPTY;
	private List<ISelectionChangedListener> selectionChangedListenerList = new ArrayList<ISelectionChangedListener>();
	

	@Override
	public void doSave(IProgressMonitor monitor) 
	{
		if (filename == null){
			boolean finished = false;
			while(!finished){
				FileDialog fileDialog = new FileDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), SWT.SAVE);
				fileDialog.setFilterPath("C:/");
				String[] extensions = { "*.xml", "*.*" };
				fileDialog.setFilterExtensions(extensions);
				filename = fileDialog.open();
				if((filename == null))return;
				File file = new File(filename);
		        if (file.exists()) {
		          MessageBox ensure = new MessageBox(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), SWT.ICON_WARNING | SWT.YES | SWT.NO);
		          ensure.setMessage(filename + " already exists. Do you want to replace it?");
		          if (ensure.open() == SWT.YES) finished = true;
		          else {
		        	  finished = false;
		        	  continue;
		          }
		        }
		        else finished = true;
				XMLWriter writer = new XMLWriter(filename);
				writer.saveXMLDocument();
			}
		}
		else {
			XMLWriter writer = new XMLWriter(filename);
			writer.saveXMLDocument();
		}
				
		this.setDirty(false);
	}
	
	

	@Override
	public void doSaveAs() 
	{

	}

	@Override
	public boolean isSaveAsAllowed() 
	{
		return false;
	}
	
	@Override
	public boolean isDirty() 
	{
		return this.dirty;
	}
	
	public void setDirty(boolean dirty)
	{
		this.dirty = dirty;
		firePropertyChange(PROP_DIRTY);
	}
	
	@Override
	public void init(IEditorSite site, IEditorInput input)throws PartInitException 
	{
		setSite(site);
		setInput(input);
		
		super.setPartName("VisualOS Editor");
		super.setTitleImage(null);
	}

	@Override
	public void createPartControl(Composite parent) 
	{
		parent.addListener(SWT.Resize, this);
		
		
		canvas = new FigureCanvas(parent);
		canvas.setScrollBarVisibility(FigureCanvas.NEVER);
		getSite().setSelectionProvider(this);
		
	    //***********add Listeners to Menu********************************************
	    
	    appContents.setLayoutManager(appContentsLayout);
	    
	    selectorPane.setContents(selector);
	    editorPane.setContents(editor);
	    appContents.add(selectorPane);
	    appContents.add(editorPane);
	    
	    //**********Add Listener to Main Content Figure*************************************************
	    
	    appContents.addMouseListener(new MouseListener() {
	    	Figure tempFig;
			@Override
			public void mouseReleased(MouseEvent me) {
				for (int i = 0; i < appContents.getChildren().size(); i++){
					tempFig = (Figure)appContents.getChildren().get(i);
					if(tempFig instanceof Module){
						if(me.x>250){
							((Module)tempFig).setDeselected();
							((Module)tempFig).generateID();
							editor.add(tempFig);
							VOSEditor.this.setDirty(true);
						}
						else {
							appContents.getChildren().remove(i);
							appContents.repaint();
						}
						
					}
				}
				
			}
			
			@Override
			public void mousePressed(MouseEvent me) {
				
				
				if(me.x < 250){
					if (selector.findFigureAt(me.x, me.y)!= null && selector.findFigureAt(me.x, me.y)!= selector){
							tempFig = (Figure)selector.findFigureAt(me.x, me.y);
							while (!(tempFig instanceof Module)){
								try{
									tempFig = (Figure)tempFig.getParent();
								}catch (NullPointerException e){
									
								}
							}
							Module m = parser.getModuleByID(((Module)tempFig).getID());
							Point p = tempFig.getLocation();
							m.setLocation(p);
							appContentsLayout.setConstraint(m, new Rectangle(m.getLocation().x,m.getLocation().y,m.getWidth(),m.getHeight()));
							setAdjustment(me.x-p.x, me.y-p.y);
							appContents.add(m);
							m.setSelected();
							
							VOSEditor.this.structuredSelection = new StructuredSelection(new Module[]{m});
						}
					}
				
				
			}
			
			@Override
			public void mouseDoubleClicked(MouseEvent me) {
				// TODO Auto-generated method stub
				
			}
		});
	    
	    appContents.addMouseMotionListener(new MouseMotionListener(){
	    	
	    	Figure tempFig;
			@Override
			public void mouseDragged(MouseEvent me) {
				
				for (int i = 0; i < appContents.getChildren().size(); i++){
					tempFig = (Figure)appContents.getChildren().get(i);
					if(tempFig instanceof Module){
						Point p = new Point(me.x-xAdjust, me.y-yAdjust);
						tempFig.setLocation(p);
					}
				}
				
			}

			@Override
			public void mouseEntered(MouseEvent me) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void mouseExited(MouseEvent me) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void mouseHover(MouseEvent me) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void mouseMoved(MouseEvent me) {
				// TODO Auto-generated method stub
				
			}
	    	
	    });
	    
	    appContentsLayout.setConstraint(selectorPane, new Rectangle(0,0,250,canvas.getParent().getParent().getParent().getParent().getBounds().height-30));
		appContentsLayout.setConstraint(editorPane, new Rectangle(250,0,canvas.getParent().getParent().getParent().getParent().getBounds().width-255,canvas.getParent().getParent().getParent().getParent().getBounds().height-30));
		canvas.setContents(appContents);
		
		MenuManager menuManager = new MenuManager();
		menuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
		canvas.setMenu(menuManager.createContextMenu(canvas));
		
		getSite().registerContextMenu("main.editor.VOSEditor", menuManager, this);

	}

	@Override
	public void dispose() 
	{
		Activator.getDefault().getSimulationController().dispose(this);
		super.dispose();
	}

	@Override
	public void setFocus() 
	{
		Activator.getDefault().getSimulationController().setFocus(this);
	}
	
	public ModuleEditor getModuleEditor(){
		return this.editor;
	}
	
	private void setAdjustment(int x, int y){
		xAdjust = x;
		yAdjust = y;
	}
	
	public void refreshSelector(String filename){
		parser = new XMLParser(filename);
		selector.removeAll();
		
    	ArrayList<Module> al = new ArrayList<Module>();
    	al = parser.getXMLModules();
    	for(int i = 0; i < al.size(); i++){
    		selector.addFigure(al.get(i));
    	}
	}
	
	public void setFilename(String filename) {
		this.filename = filename;
	}
	

	@Override
	public void handleEvent(Event event) {
		if(canvas.getBounds().height != 0){

			appContentsLayout.setConstraint(selectorPane, new Rectangle(0,0,250,canvas.getParent().getParent().getParent().getParent().getBounds().height-30));
			appContentsLayout.setConstraint(editorPane, new Rectangle(250,0,canvas.getParent().getParent().getParent().getParent().getBounds().width-255,canvas.getParent().getParent().getParent().getParent().getBounds().height-30));
		}
		
	}

	@Override
	public void addSelectionChangedListener(ISelectionChangedListener listener) 
	{
		this.selectionChangedListenerList.add(listener);
	}

	@Override
	public ISelection getSelection() 
	{
		return this.structuredSelection;
	}

	@Override
	public void removeSelectionChangedListener(ISelectionChangedListener listener) 
	{
		this.selectionChangedListenerList.remove(listener);
	}

	@Override
	public void setSelection(ISelection selection) 
	{
		if(selection instanceof StructuredSelection)
		{
			this.structuredSelection = (StructuredSelection)selection;
		}
	}

	public List<ISelectionChangedListener> getSelectionChangedListenerList() 
	{
		return selectionChangedListenerList;
	}

}
